package com.ujoku.controller;

import com.labillusion.core.platform.web.pagination.PaginationForm;
import com.labillusion.core.platform.web.rest.RESTController;
import com.labillusion.core.platform.web.rest.exception.InvalidRequestException;
import com.labillusion.core.util.SequenceNumUtils;
import com.ujoku.context.ActionContext;
import com.ujoku.context.constants.ContextConstants;
import com.ujoku.context.constants.ExpiredCacheContext;
import com.ujoku.domain.*;
import com.ujoku.domain.admin.Parameter;
import com.ujoku.interceptor.LoginRequired;
import com.ujoku.payment.alipay.AlipayCore;
import com.ujoku.payment.alipay.AlipaySubmit;
import com.ujoku.request.PaymentReturnForm;
import com.ujoku.request.RechargeCreateForm;
import com.ujoku.request.RechargeSendForm;
import com.ujoku.request.WithdrawForm;
import com.ujoku.service.MemberBalanceLogService;
import com.ujoku.service.MemberService;
import com.ujoku.service.admin.ParametersService;
import com.ujoku.view.domain.MemberBalanceLogView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;


@RestController
public class MemberBalanceLogController extends RESTController {

    private final Logger logger = LoggerFactory.getLogger(MemberBalanceLogController.class);

    @Autowired
    private MemberBalanceLogService memberBalanceLogService;

    @Autowired
    private ActionContext actionContext;

    @Autowired
    private MemberService memberService;

    @Autowired
    private ParametersService parametersService;

    @RequestMapping(value="/memberBalanceLog/list", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public MemberBalanceLogView memberBalanceLogList(@RequestBody @Valid PaginationForm form) {
        Member member = actionContext.getMember();

        Map<String,Object> query = form.getQueryMap();
        query.put("memberId", member.getUser_id());

        int count = memberBalanceLogService.selectCount(query);
        List<MemberBalanceLog> list =  memberBalanceLogService.selectListByMember(query);

        query.put("status", MemberBalanceLogStatus.CREATED);
        count -= memberBalanceLogService.selectCount(query);

        MemberBalanceLogView view = new MemberBalanceLogView();
        view.setMember(member);
        view.setMemberBalanceLogList(list);
        view.setCount(count);

        return view;
    }

    @RequestMapping(value="/recharge/create", method = RequestMethod.POST)
    @LoginRequired
    @ResponseBody
    public MemberBalanceLog create(@RequestBody @Valid RechargeCreateForm form) {
        Member member = actionContext.getMember();
        MemberBalanceLog log = createMemberBalanceLog(form.getAmount(), member);

        return log;
    }

    private MemberBalanceLog createMemberBalanceLog(Double amount, Member member) {
        MemberBalanceLog log = new MemberBalanceLog();
        log.setId("R" + SequenceNumUtils.generateNum());
        log.setMemberId(member.getUser_id());
        log.setStatus(MemberBalanceLogStatus.CREATED);
        log.setType(MemberBalanceLogType.RECHARGE);
        log.setAmount(amount);

        memberBalanceLogService.insert(log);
        return log;
    }


    @RequestMapping(value="/alipay/recharge", method = RequestMethod.POST)
    @LoginRequired
    @ResponseBody
    public String rechargeAlipaySend(@RequestBody @Valid RechargeSendForm form, HttpServletRequest request) {

        Member member = actionContext.getMember();

        MemberBalanceLog log = createMemberBalanceLog(form.getAmount(), member);

        Map<String, String> sParaTemp = AlipayCore.buildRechargeRequestMap(request, form.getReturn_url(), log);

        //建立请求
        String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "确认");
        return sHtmlText;
    }

    @RequestMapping(value="/alipay/recharge/return", method = RequestMethod.POST)
    @LoginRequired
    @ResponseBody
    public String alipayReturn(@RequestBody @Valid PaymentReturnForm form){

        AlipayCore.verifyReturnRequest(form.getParams());

        Map<String,String> params = form.getParams();
        //商户订单号
        String out_trade_no = params.get("out_trade_no");
        //支付宝交易号
        String trade_no = params.get("trade_no");
        //交易状态
        String trade_status = params.get("trade_status");
        MemberBalanceLog log = (MemberBalanceLog) memberBalanceLogService.selectById(out_trade_no);
        if(log.getStatus() > MemberBalanceLogStatus.CREATED)
            return "success";

        if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
            rechargeComplete(trade_no, log);
        }

        return "success";
    }

    private void rechargeComplete(String trade_no, MemberBalanceLog log) {
        log.setStatus(MemberBalanceLogStatus.DONE);
        log.setTradeNo(trade_no);
        memberBalanceLogService.update(log);

        Member member = (Member) memberService.selectById(log.getMemberId());
        member.setBalance(member.getBalance() + log.getAmount());

        List<Parameter> upgradeList = parametersService.getUpgradeList();
        Double chargeTotal = memberBalanceLogService.getChargeTotalByMemberId(member.getUser_id());

        for(int i = 0;i< upgradeList.size();i++){
            Parameter item =  upgradeList.get(i);
            if(chargeTotal >= Double.parseDouble(item.getValue()))
                member.setLevel(i+1);
        }

        memberService.update(member);

        ExpiredCacheContext.expiredMemberSet.add(member.getUser_id());

    }

    @RequestMapping(value="/alipay/recharge/notify")
    @ResponseBody
    public String alipayNotify(HttpServletRequest request){

        AlipayCore.verifyReturnRequest(request);

        //商户订单号
        String out_trade_no = request.getParameter("out_trade_no");
        //支付宝交易号
        String trade_no = request.getParameter("trade_no");
        //交易状态
        String trade_status = request.getParameter("trade_status");

        MemberBalanceLog log = (MemberBalanceLog) memberBalanceLogService.selectById(out_trade_no);
        if(log.getStatus() > MemberBalanceLogStatus.CREATED)
            return "success";

        if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {

            rechargeComplete(trade_no, log);
            return "success";
        }

        return "fail";
    }

    @RequestMapping(value="/withdraw", method = RequestMethod.POST)
    @LoginRequired
    @ResponseBody
    public String addWithdraw(@RequestBody @Valid WithdrawForm form){
        if(form.getAmount() <= 0)
            throw new InvalidRequestException("amount under 0");

        Member member = actionContext.getMember();

        if(member.getBalance() < form.getAmount()){
            throw new InvalidRequestException("balance","余额不足");
        }

        MemberBalanceLog log = new MemberBalanceLog();
        log.setId("W" + SequenceNumUtils.generateNum());
        log.setMemberId(member.getUser_id());
        log.setStatus(MemberBalanceLogStatus.CREATED);
        log.setType(MemberBalanceLogType.WITHDRAW);
        log.setAmount(form.getAmount());
        log.setBank(form.getBank());
        log.setAccount(form.getAccount());
        log.setAccountName(form.getAccountName());

        memberBalanceLogService.insert(log);

        member.setBalance(member.getBalance() - form.getAmount());
        memberService.update(member);

        actionContext.setMember(member);
        return "successfully";
    }

}